import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_map_demo/t3_map_plugin/map/core/t3_annotation.dart';
import 'package:stream_transform/stream_transform.dart';

import 'core/t3_map_event.dart';

/// 地图的监听类，用于监听原生地图事件的回调信息
class T3MapEventStream {

  T3Annotation? Function(String id)? findAnnotationById;

  final StreamController<T3MapEvent> _mapEventStreamController = StreamController<T3MapEvent>.broadcast();

  T3MapEventStream() {

    /// iOS平台的特殊处理，将T3MapCompleteEvent通过didFinishLoading来实现
    /// Android平台依旧使用系统原生的地图加载完成事件
    if (Platform.isIOS) {
      /// 地图初始化完成时机调整为首次地图加载成功
      /// 在onMapInitCompleted事件中，添加Annotation和showAnnotation会出现位置显示错乱问题，临时通过该方式进行修复
      bool hasInit = false;
      _didFinishLoading().listen((event) {
        if (hasInit != true) {
          hasInit = true;  
          _mapEventStreamController.add(const T3MapCompleteEvent(value: true));
        }
      });
    }
  }

  /// note: 内部事件。地图加载成功，外部监听请使用onMapInitCompleted
  Stream<T3MapDidFinishLoadingEvent> _didFinishLoading() {
    return _mapEventStreamController.stream.whereType<T3MapDidFinishLoadingEvent>();
  }

  //地图创建加载完成事件监听
  Stream<T3MapCompleteEvent> onMapInitCompleted() {
    return _mapEventStreamController.stream.whereType<T3MapCompleteEvent>();
  }

  /// 地图区域即将改变时会调用此接口
  Stream<T3MapRegionWillChangeEvent> regionWillChange() {
    return _mapEventStreamController.stream.whereType<T3MapRegionWillChangeEvent>();
  }

  /// 地图区域改变过程中会调用此接口
  Stream<T3MapRegionChangedEvent> regionChanged() {
    return _mapEventStreamController.stream.whereType<T3MapRegionChangedEvent>();
  }

  /// 地图区域改变完成后会调用此接口
  Stream<T3MapRegionDidChangeEvent> regionDidChange() {
    return _mapEventStreamController.stream.whereType<T3MapRegionDidChangeEvent>();
  }

  /// 点击地图路线回调
  Stream<T3MapDidTapPolylineEvent> polylineDidTap() {
    return _mapEventStreamController.stream.whereType<T3MapDidTapPolylineEvent>();
  }

  /// 点击地图标注物回调
  Stream<T3MapDidTapAnnotationEvent> annotationDidTap() {
    return _mapEventStreamController.stream.whereType<T3MapDidTapAnnotationEvent>();
  }

  /// 地图触摸事件
  Stream<T3MapTouchEvent> mapTouchEvent(){
    return _mapEventStreamController.stream.whereType<T3MapTouchEvent>();
  }

  //处理native向原生进行通信
  Future<dynamic> handleMethodCall(MethodCall call) async {
    switch (call.method) {
      case 'map#didFinishLoadingMap':
      if(Platform.isIOS) {
        _mapEventStreamController.add(const T3MapDidFinishLoadingEvent(value: true));
      }
      break;
      case 'map#initComplete':
      /// 这个方法目前仅Android适用，
      if(Platform.isIOS == false) {
        _mapEventStreamController.add(const T3MapCompleteEvent(value: true));
      }
      break;
      case 'map#regionWillChange':
      _mapEventStreamController.add(T3MapRegionWillChangeEvent(value: T3MapActionEventValue.fromString(call.arguments)));
      break;
      case 'map#regionChanged':
      final value = T3MapRegionChangedValue.fromString(call.arguments);
      if(value != null) {
        _mapEventStreamController.add(T3MapRegionChangedEvent(value: value));
      }
      else {
        debugPrint("map#regionChanged事件异常，数据模型转换失败");
      }
      break;
      case 'map#regionDidChange':
      _mapEventStreamController.add(T3MapRegionDidChangeEvent(value: T3MapActionEventValue.fromString(call.arguments)));
      break;
      case 'map#didTapPolyline':
      if (call.arguments is String) {
        var routeID = call.arguments as String;
        _mapEventStreamController.add(T3MapDidTapPolylineEvent(value: routeID));
        print('-----------didTapPolyline, routeID = $routeID');
      } else {
        print('-----------didTapPolyline, arguments Not available. ${call.arguments}');
      }
      break;
      case 'map#didTapAnnotation':
      final identifer = _findAnnotationId(call.arguments);
      if (identifer != null) {
        ///根据id，找到对应的Annotation
        if (findAnnotationById != null) {
          final result = findAnnotationById!(identifer);
          if (result != null) {
            _mapEventStreamController.add(T3MapDidTapAnnotationEvent(value: result));
          } else {
            //TODO: 日志  
          }
        } else {
          //TODO: 日志  
        }
      }
      else {
        //TODO: 日志
      }
      break;
      case 'map#onTouch':
        _mapEventStreamController.add(T3MapTouchEvent(value: true));
        break;
    }
  }

  String? _findAnnotationId(dynamic arguments) {
    if (arguments is String) {
      try {
        final json = jsonDecode(arguments);
        final identifier = json['identifier'];
      
        if (identifier is String) {
          return identifier;
        } else {
          return null;
        }
      } catch (e) {
        return null;
      }
    } else {
      return null;
    }
  }
}